<script setup lang="ts">
import type { ButtonFormType, ButtonOpenType } from '@uni-helper/uni-app-types'

/**
 * @description 适用于此项目业务需求的 Button 组件。
 *
 * @propertytype - 按钮的类型，默认为 primary。
 * @propertysize - 按钮的尺寸，默认为 large。
 * @propertycorner - 按钮的圆角，默认为 capsule。
 * @propertyloading - 按钮是否处于加载中状态。
 * @propertyformType - Form Type。
 * @propertyopenType - 微信小程序开放能力。
 * @propertydisabled - 按钮是否处于禁用状态。
 * @propertywidth - 指定宽度，单位 rpx。
 */
interface RGButtonProps {
  type?: 'primary' | 'secondary'
  size?: 'large' | 'medium' | 'small'
  corner?: 'capsule' | 'small'
  loading?: boolean
  formType?: ButtonFormType
  openType?: ButtonOpenType
  disabled?: boolean
  width?: string | number
  autoWidth?: boolean
}

const props = withDefaults(defineProps<RGButtonProps>(), {
  type: 'primary',
  size: 'large',
  corner: 'capsule',
  loading: false,
  formType: undefined,
  openType: undefined,
  disabled: false,
  autoWidth: false,
})

defineEmits(['getphonenumber'])

/**
 * @description 根据给定参数计算 padding。
 */
function calculatePadding() {
  switch (props.size) {
    case 'large':
      return '35rpx 0'
    case 'medium':
      return '22rpx 0'
    case 'small':
      return '14rpx 18rpx'
    default:
      return '35rpx 0'
  }
}

/**
 * @description 根据给定参数计算 width。
 */
function calculateWidth() {
  if (props.autoWidth)
    return '120rpx'

  if (props.width)
    return `${props.width}rpx`
  switch (props.size) {
    case 'large':
      return '630rpx'
    case 'medium':
      return '206rpx'
    case 'small':
      return 'auto'
    default:
      return '630rpx'
  }
}

/**
 * @description 根据给定参数计算背景颜色。
 */
function calculateBackgroundColor() {
  switch (props.type) {
    case 'primary':
      return '#FF6D0A'
    case 'secondary':
      return '#FFFFFF'
    default:
      return '#FF6D0A'
  }
}

/**
 * @description 根据给定参数计算按下时的背景颜色。
 */
function calculateTappedBackgroundColor() {
  switch (props.type) {
    case 'primary':
      return '#E45D00'
    case 'secondary':
      return '#F8F8F8'
    default:
      return '#E45D00'
  }
}

/**
 * @description 根据给定参数计算前景颜色。
 */
function calculateFrontColor() {
  switch (props.type) {
    case 'primary':
      return '#FFFFFF'
    case 'secondary':
      return '#FF6D0A'
    default:
      return '#FFFFFF'
  }
}

/**
 * @description 根据给定参数计算字体大小。
 */
function calculateFontSize() {
  switch (props.size) {
    case 'large':
      return '32rpx'
    case 'medium':
      return '32rpx'
    case 'small':
      return '28rpx'
    default:
      return '32rpx'
  }
}

/**
 * @description 根据给定参数计算圆角大小。
 */
function calculateBorderRadius() {
  switch (props.corner) {
    case 'small':
      return '10rpx'
    case 'capsule':
      return '9999rpx'
    default:
      return '9999rpx'
  }
}

/**
 * @description 根据给定参数计算字重。
 */
function calculateFontWeight() {
  switch (props.size) {
    case 'large':
      return 'bold'
    case 'medium':
      return 'bold'
    case 'small':
      return 'medium'
    default:
      return 'bold'
  }
}

/**
 * @description 根据给定参数计算字重。
 */
function calculateBorder() {
  switch (props.type) {
    case 'primary':
      return ''
    case 'secondary':
      return '1rpx solid #FF6D0A'
  }
}
</script>

<template>
  <button :disabled="props.disabled" :form-type="props.formType" :open-type="props.openType" class="main uv-reset-button uv-line-1" hover-class="tapped" @getphonenumber="(e) => $emit('getphonenumber', e)">
    <view v-if="props.loading" class="flex items-center">
      <uv-loading-icon :size="calculateFontSize()" :color="calculateFrontColor()" />
      <Spacer width="16" />
      <text>加载中</text>
    </view>
    <slot v-else />
  </button>
</template>

<style scoped>
.main {
  display: flex;
  justify-content: center;
  align-items: center;
  width: v-bind('calculateWidth()');
  height: auto;
  min-height: 0;
  padding: v-bind('calculatePadding()');
  border: v-bind('calculateBorder()');
  color: v-bind('calculateFrontColor()');
  font-size: v-bind('calculateFontSize()');
  line-height: v-bind('calculateFontSize()');
  font-weight: v-bind('calculateFontWeight()');
  background-color: v-bind('calculateBackgroundColor()');
  border-radius: v-bind('calculateBorderRadius()');
}

.main[disabled] {
  color: v-bind('calculateFrontColor()') !important;
  background-color: v-bind('calculateBackgroundColor()') !important;
  opacity: 0.4;
}

.tapped {
  background-color: v-bind('calculateTappedBackgroundColor()');
}
</style>
